package pl.edu.agh.thieves.firefly;

import java.text.*;

/**
 * Klasa trzymaj¹ca w sobie wspó³rzêdne wietlika, czyli równie¿ informacje o
 * jednym z mo¿liwych rozwi¹zañ. Ka¿da wspó³rzêdna jest z przedzia³u od 0.0 do
 * 2.0 (bez 2.0). Interpretacja w problemie plecakowym: Jeli wspó³rzêdna n ma
 * wartoæ > 1.0 (wartoæ z przedzia³u od 1.0 do 2.0) wówczas oznacza to, ¿e w
 * tym rozwi¹zaniu przedmiot o numerze n zosta³ spakowany do plecaka.
 * Analogicznie wartoæ z przedzia³u od 0.0 do 1.0 oznacza nie zabranie
 * przedmiotu w tym rozwi¹zaniu.
 */
public class Coordinates {

        /**
         * Zwraca jedn¹ ze wspó³rzêdnych o podanym numerze.
         *
         * @param no
         *            numer wspó³rzêdnej
         * @return wartoæ wspó³rzêdnej
         */
        public double getCoordinateByNumber(int no) {
                return coordinates[no];
        }

        /**
         * Zmienia wspó³rzêdn¹ wietlika o podanym numerze na now¹ wartoæ.
         *
         * @param no
         *            numer zmienianej wspó³rzêdnej
         * @param newValue
         *            nowa wartoæ ustawianej wspó³rzêdnej
         */
        public void setCoordinateByNumber(int no, double newValue) {
                coordinates[no] = newValue;
        }

        /**
         * Zwraca wymiar przestrzeni. Ka¿dy wymiar jest interpretowany jako kolejny
         * przedmiot.
         *
         * @return wymiar przestrzeni
         */
        public int getDimension() {
            return coordinates.length;
    }

    public String toString() {

            DecimalFormat f = new DecimalFormat("#0.00");

            String answer = "(" + f.format(getCoordinateByNumber(0));

            for (int i = 1; i < getDimension(); ++i)
                    answer = answer + ", " + f.format(getCoordinateByNumber(i));

            answer = answer + ")";

            return answer;
    }

public boolean equals(Coordinates coordinates){
	if(getDimension() != coordinates.getDimension())
		return false;
	for(int i = 0; i < getDimension(); ++i)
		if(getCoordinateByNumber(i) != coordinates.getCoordinateByNumber(i))
			return false;
			
	return true;
}

    public static Coordinates sum(Coordinates firstCoordinates,
                    Coordinates secondCoordinates) {
            double[] newCoordinates = new double[firstCoordinates.getDimension()];

            for (int i = 0; i < firstCoordinates.getDimension(); ++i)
                    newCoordinates[i] = firstCoordinates.getCoordinateByNumber(i)
                                    + secondCoordinates.getCoordinateByNumber(i);

            return new Coordinates(newCoordinates);
    }

    public static Coordinates sub(Coordinates firstCoordinates,
                    Coordinates secondCoordinates) {
            double[] newCoordinates = new double[firstCoordinates.getDimension()];

            for (int i = 0; i < firstCoordinates.getDimension(); ++i)
                    newCoordinates[i] = firstCoordinates.getCoordinateByNumber(i)
                                    - secondCoordinates.getCoordinateByNumber(i);

            return new Coordinates(newCoordinates);
    }

    public static Coordinates multiplyByNumber(double number,
                    Coordinates coordinates) {
            double[] newCoordinates = new double[coordinates.getDimension()];

            for (int i = 0; i < coordinates.getDimension(); ++i)
                    newCoordinates[i] = number * coordinates.getCoordinateByNumber(i);

            return new Coordinates(newCoordinates);
    }

    public static Coordinates addNumber(Coordinates coordinates, double number) {
            double[] newCoordinates = new double[coordinates.getDimension()];

            for (int i = 0; i < coordinates.getDimension(); ++i)
                    newCoordinates[i] = coordinates.getCoordinateByNumber(i) + number;

            return new Coordinates(newCoordinates);
    }

    public double getVectorLength() {
            double sum = 0;

            for (double value : coordinates)
                    sum += value * value;

            return Math.sqrt(sum);
    }

    public Coordinates(double[] coordinates) {
            this.coordinates = coordinates;
    }

    public Coordinates(int dimensionNumber) {
            coordinates = new double[dimensionNumber];

            for (int i = 0; i < dimensionNumber; ++i)
                    coordinates[i] = Math.random() * 2;

    }

    private double[] coordinates = null;

}

